package com.songlanyun.modules.coupon.entity;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.songlanyun.common.drive.RootEntity;
import com.songlanyun.common.enums.CouponConstant;
import com.songlanyun.common.utils.custom.MathUtils;
import com.songlanyun.modules.coupon.model.vo.AdaptActivityVo;
import com.songlanyun.modules.coupon.service.CouponGoodsService;
import com.songlanyun.modules.coupon.service.CouponShopService;
import com.songlanyun.modules.goods.model.vo.GoodsSuperSlimVo;
import com.songlanyun.modules.rabbitmq.util.SpringContextUtil;
import com.songlanyun.modules.shop.model.vo.ShopSlimVO;
import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;

/**
 * 优惠券
 *
 * @author lubo
 * @email sunlightcs@gmail.com
 * @date 2022-07-05 15:20:02
 */
@Data
@TableName("yxt_coupon")
public class CouponEntity extends RootEntity<Long, CouponEntity> implements Serializable {
	private static final long serialVersionUID = 1L;
	{
		type = CouponConstant.CouponType.FULL_REDUCE;
	}

	/**
	 *
	 */
	@TableId
	private Long id;

	/**
	 * 编号
	 */
	private String code;
	/**
	 * 优惠券名称
	 */
	private String name;
	/**
	 * 优惠券范围 0:平台通用券，1:店铺券
	 */
	private CouponConstant.CouponMode mode;

	/**
	 * 优惠券特征 0:普通券，1:新人券
	 */
	private CouponConstant.CouponTrait trait;
	/**
	 * 是否是通用券
	 */
	private Boolean universal;
	/**
	 * 1:满减券
	 */
	private CouponConstant.CouponType type;
	/**
	 * 优惠券优惠额度
	 */
	private BigDecimal faceValue;
	/**
	 * 是否存在门槛
	 */
	private Boolean hasThreshold;
	/**
	 * 门槛值
	 */
	private BigDecimal threshold;
	/**
	 * 发行数量(-1代表不限量)
	 */
	private Integer issueNumber;
	/**
	 * 0000001，适应首单优惠，00000010适应秒杀，00000100适应拼团
	 */
	private Integer adaptActivity;

	@TableField(exist = false)
	private List<AdaptActivityVo> adaptActivityData;

	public List<AdaptActivityVo> getAdaptActivityData()
	{
		if(CollectionUtil.isEmpty(adaptActivityData)) {
			adaptActivityData = new ArrayList<>();
			Set<Map.Entry<CouponConstant.ActivityCouponType, Integer>> entries = CouponConstant.ADAPT_ACTIVITY.entrySet();
			for (Map.Entry<CouponConstant.ActivityCouponType, Integer> entry : entries) {
				CouponConstant.ActivityCouponType key = entry.getKey();
				Integer value = entry.getValue();
				AdaptActivityVo adaptActivityVo = new AdaptActivityVo();
				adaptActivityVo.setCode(key.getCode());
				adaptActivityVo.setOn(MathUtils.andOperation(value, this.adaptActivity));
				adaptActivityData.add(adaptActivityVo);
			}
		}
		return adaptActivityData;
	}


	/**
	 * 是否适配首单优惠
	 * @return
	 */
	public Boolean isAdaptFirstOrder()
	{
		return MathUtils.andOperation(CouponConstant.ADAPT_ACTIVITY.get(CouponConstant.ActivityCouponType.FIRST_ORDER), this.adaptActivity);
	}

	/**
	 * 是否适配秒杀
	 * @return
	 */
	public Boolean isAdaptSecKill()
	{
		return MathUtils.andOperation(CouponConstant.ADAPT_ACTIVITY.get(CouponConstant.ActivityCouponType.SECKILL), this.adaptActivity);
	}

	/**
	 * 是否适配拼团
	 * @return
	 */
	public Boolean isAdaptGroupBuy()
	{
		return MathUtils.andOperation(CouponConstant.ADAPT_ACTIVITY.get(CouponConstant.ActivityCouponType.GROUP_BUY), this.adaptActivity);
	}



	/**
	 * 领取数量
	 */
	private Integer receiveNum;

	/**
	 * 每人限领多少张（用了之后给再领取）
	 */
	private Integer receiveLimit;
	/**
	 * 开始时间
	 */
	private Date startTime;
	/**
	 * 领取后过期天数
	 */
	private Integer expiredDay;
	/**
	 * 结束时间
	 */
	private Date endTime;
	/**
	 * 发行的店铺
	 */
	private Long shopId;

	/**
	 * 描述
	 */
	private String content;

	/**
	 * 优惠券状态 0已终止，1待发布，2已发布
	 */
	private CouponConstant.CouponStatus status;

	@TableField(fill = FieldFill.INSERT)
	private Date createTime;

	@TableField(fill = FieldFill.INSERT_UPDATE)
	private Date updateTime;


	@Override
	public Long getIdentity() {
		return getId();
	}


	/**
	 * 适合或不适合
	 */
	private Boolean adaptOrNo;

	/**
	 * 如果是平台券，那些店铺适合或不适合
	 */
	@TableField(exist = false)
	private List<ShopSlimVO> adaptShops;
	public List<ShopSlimVO> loadAdaptShops()
	{
		if(CouponConstant.CouponMode.PLATFORM.equals(this.mode) && adaptShops == null)
		{
			CouponShopService couponShopService = (CouponShopService) SpringContextUtil.getBean("couponShopService");
			adaptShops = couponShopService.loadAdaptShops(this.getId());
		}
		return adaptShops;
	}


	/**
	 * 如果是店铺券，那些商品适合或不适合
	 */
	@TableField(exist = false)
	private List<GoodsSuperSlimVo> adaptGoods;
	public List<GoodsSuperSlimVo> loadAdaptGoods()
	{
		if(CouponConstant.CouponMode.SHOP.equals(this.mode) &&adaptGoods == null)
		{
			CouponGoodsService couponGoodsService = (CouponGoodsService) SpringContextUtil.getBean("couponGoodsService");
			adaptGoods = couponGoodsService.loadAdaptGoods(this.getShopId(),this.getId());
		}
		return adaptGoods;
	}


	/**
	 * 活动状态
	 * @return
	 */
	public CouponConstant.UseStatus getActiveState()
	{
		Date now = new Date();

		if(CouponConstant.CouponStatus.STOP.equals(this.getStatus()))
		{
			return CouponConstant.UseStatus.STOP;
		}

		if(DateUtil.compare(now,this.getEndTime())>=0)
		{
			return CouponConstant.UseStatus.COMPLETE;
		}

		if(CouponConstant.CouponStatus.WAIT_RELEASE.equals(this.getStatus()))
		{
			return CouponConstant.UseStatus.WAIT_RELEASE;
		}

		if(CouponConstant.CouponStatus.RELEASED.equals(this.getStatus()) &&  DateUtil.compare(now,this.getStartTime()) >= 0 && DateUtil.compare(now,this.getEndTime()) < 0)
		{
			return CouponConstant.UseStatus.NORMAL;
		}

		if(CouponConstant.CouponStatus.RELEASED.equals(this.getStatus()) &&  DateUtil.compare(now,this.getStartTime()) < 0 )
		{
			return CouponConstant.UseStatus.RELEASED;
		}

		return CouponConstant.UseStatus.COMPLETE;
	}

	/**
	 * 是否可以领取
	 * @param num
	 * @return
	 */
	public Integer canReceive(Integer num)
	{
		if(CouponConstant.UseStatus.COMPLETE.equals(this.getActiveState()))
		{
			return -1;
		}

		if(CouponConstant.UseStatus.STOP.equals(this.getActiveState()))
		{
			return -2;
		}

		if(CouponConstant.UseStatus.WAIT_RELEASE.equals(this.getActiveState()))
		{
			return -3;
		}

		if(CouponConstant.UseStatus.RELEASED.equals(this.getActiveState()))
		{
			return -4;
		}

		if(this.getIssueNumber()!=-1 && (this.getIssueNumber()-this.getReceiveNum())<num)
		{
			return -5;
		}
		return 1;

	}

}
